<?php
namespace {
    /**
    * 企业微信封装主类
    * @author Jamers
    * @since 2016.12.31
    */

    class Qywx {
        /**
        * 公用基础类
        * 
        * @var \Qy\Common
        */
        public $Common;         //Common类
        /**
        * Oauth类
        * 
        * @var \Qy\Oauth
        */
        public $Oauth;          //Oauth类
        /**
        * 应用管理类
        * 
        * @var \Qy\Agent
        */
        public $Agent;          //Agent类
        /**
        * 菜单管理类
        * 
        * @var \Qy\Menu
        */
        public $Menu;           //菜单类
        /**
        * 成员管理类
        * 
        * @var \Qy\User
        */
        public $User;           //成员管理类
        /**
        * 部门管理类
        * 
        * @var \Qy\Department
        */
        public $Department;     //部门管理类
        /**
        * 标签管理类
        * 
        * @var \Qy\Tag
        */
        public $Tag;            //标签管理类
        /**
        * 异步任务接口类
        * 
        * @var \Qy\Batch
        */
        public $Batch;          //异步任务接口类
        /**
        * 素材管理类
        * 
        * @var \Qy\Media
        */
        public $Media;          //素材文件管理类
        //public $MessageBody;    //回复消息生成类
        /**
        * 消息发送类
        * 
        * @var \Qy\Message
        */
        public $Message;        //发送消息类
        /**
        * 会话管理类
        * 
        * @var \Qy\Chat
        */
        public $Chat;           //会话服务类
        /**
        * 客服服务类
        * 
        * @var \Qy\Kf
        */
        public $Kf;             //客服服务类
        /**
        * 摇一摇周边类
        * 
        * @var \Qy\Shake
        */
        public $Shake;
        /**
        * 卡券服务类
        * 
        * @var \Qy\Card
        */
        public $Card;
        /**
        * 第三方应用接口类
        * 
        * @var \Qy\Service
        */
        public $Service;
        
        private $message_type = array('text', 'image', 'voice', 'video', 'file', 'news', 'mpnews',);
        private $recvice_type = array('text', 'image', 'voice', 'video', 'shortvideo', 'location', 'link', 'event',);
        private $event_type = array('subscribe', 'unsubscribe', 'LOCATION', 'click', 'view', 'scancode_push', 'scancode_waitmsg', 'pic_sysphoto', 'pic_photo_or_album', 'pic_weixin', 'location_select', 'enter_agent', 'batch_job_result',);
        
        /**
        * 企业微信类构造函数
        * 
        * @param mixed $corpid
        * @param mixed $corpsecret
        * @param mixed $token
        * @param mixed $encodingAesKey
        */
        public function __construct($corpid='',$corpsecret='',$token='',$encodingAesKey='') {
            if (!is_object($this->Common)) {
                $ary = array('corpid'=>$corpid, 'corpsecret'=>$corpsecret, 'token'=>$token, 'aeskey'=>$encodingAesKey, 'accesstoken'=>'');
                $this->Common = new \Qy\Common($ary);
            }else{
                if ($corpid) $this->Common->corpid = $corpid;
                if ($corpsecret) $this->Common->corpsecret = $corpsecret;
                if ($token) $this->Common->token = $token;
                if ($encodingAesKey) $this->Common->encodingAesKey = $encodingAesKey;
            }
        }
        
        /**
        * 初始化Token/AESKey参数
        * 
        * @param mixed $corpid
        * @param mixed $token
        * @param mixed $encodingAesKey
        */
        public function init_token($corpid='',$token='',$encodingAesKey='') {
            $this->Common->init_token($corpid, $token, $encodingAesKey);
        }
        
        private function BuildParams() {
            //array('corpid'=>'', 'corpsecret'=>'', 'token'=>'', 'aeskey'=>'', 'accesstoken'=>'')
            return array(
                'corpid'=>$this->Common->corpid,
                'corpsecret' => $this->Common->corpsecret,
                'token' => $this->Common->token,
                'aeskey' => $this->Common->encodingAesKey,
                'accesstoken' => $this->Common->read_access_token(),
                'common' => &$this->Common,
            );
        }
        
        /**
        * 加载类函数
        * 
        * @param {'类名'|'ALL'|array('类名1','类名2')}
        */
        public function LoadClass($class) {
            if (empty($class)) return false;
            if (is_string($class)) {
                if ($class == 'ALL') {
                    foreach(get_class_vars(__CLASS__) as $k => $v) {
                        if (($k != 'ALL')&&($k != 'Common') && (!is_array($v)) && ($v === NULL)) {
                            $this->LoadClass($k);
                        }
                    }
                    return true;
                }
                $uclass = ucfirst($class);
                if (isset($this->$class) && is_object($this->$class)) return true;
                $c = "\\Qy\\{$uclass}";
                //$this->$class = new $c;
                $this->$class = $this->newInst($c,$this->BuildParams());
                return $this->$class;
            }else if (is_array($class)) {
                foreach ($class as $v) {
                    $this->LoadClass($v);
                }
            }
            return true;
        }
        private function newInst() {
            //取得所有参数
            $arguments = func_get_args();

            //弹出第一个参数，这是类名，剩下的都是要传给实例化类的构造函数的参数了
            $className = array_shift($arguments);

            //给所有的参数键值加个前缀
            $keys = array_keys($arguments);
            array_walk($keys, create_function('&$value, $key, $prefix', '$value = $prefix . $value;'), '$arg_');

            //动态构造实例化类的函数，主要是动态构造参数的个数
            $paramStr = implode(', ',$keys);
            $newClass=create_function($paramStr, "return new {$className}({$paramStr});");

            //实例化对象并返回
            return call_user_func_array($newClass, $arguments);
        }

    }
}
?>
